package com.yfl.config;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.yfl.constant.GatewallConstant;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.StringUtils;
import reactor.core.publisher.Mono;

import java.time.Duration;

/**
 * 给授权做代码方式的路由
 */
@Configuration
public class LoginRoute {

    @Autowired
    private StringRedisTemplate redisTemplate;

    /**
     * auth-server ----> gateway 存储jwt
     * <p>
     * 现在一个 员工张三 他有自己的一些权限 sys:add  sys:update  sys:del    张三现在保持登录
     * 你是一个超级管理员  你想在张三登录的期间把张三的权限改了   sys:del 这个权限删了
     * <p>
     * 想删除redis的jwt  怎么定位某一个员工的token
     * <p>
     * 换一种存储方式
     * redis key  id
     * value jwt
     * <p>
     * 我们怎么在网关里面拿到用户的id呢？
     * 我们给auth-server授权的接口做一个aop  把用户的id携带上 即可
     * <p>
     * RBAC 用户 角色 权限 菜单   CAR
     *
     * @param builder
     * @return
     */

    @Bean
    public RouteLocator routeLocator(RouteLocatorBuilder builder) {
        return builder.routes()
                .route("auth-server-router-id", r -> r.path("/oauth/token")
                        .filters(f -> f.modifyResponseBody(String.class, String.class, (exchange, s) -> {
                            // 拿到响应值
                            JSONObject jsonObject = JSON.parseObject(s);
                            String acccessToken = jsonObject.getString("acccess_token");
                            if (StringUtils.hasText(acccessToken)) {
                                // 有token 就存redis
                                Long expires = jsonObject.getLong("expires_in");
                                redisTemplate.opsForValue()
                                        .set(GatewallConstant.OAUTH_PREFIX + acccessToken, "", Duration.ofSeconds(expires));
                            }
                            return Mono.just(s);
                        })).uri("lb://auth-server"))
                .build();
    }
}

